/**
 * 适用于NodeJS支持的Buffer的实现类
 */
var createNodeBuffer = (function () {
    if ('allocUnsafe' in Buffer) {
        return function (data) {
            return Buffer.allocUnsafe(data);
        }
    } else {
        return function (data) {
            return new Buffer(data);
        }
    }
}());


class LiteBuffer{
    innerbuffer = undefined;

    constructor(size) {
        this.allocUnsafe(size);
    }

    allocUnsafe(size) {
        this.innerbuffer = new ArrayBuffer(size);
    }

    // subarray(begin?, end?): LiteBuffer;

    // readBigUInt64BE(offset): bigint;
    // readBigUInt64LE(offset): bigint;
    // readBigInt64BE(offset): bigint;
    // readBigInt64LE(offset): bigint;
    // readUIntLE(offset, byteLength);
    // readUIntBE(offset, byteLength);
    // readIntLE(offset, byteLength);
    // readIntBE(offset, byteLength);
    readUInt8(offset) {
        if (offset == undefined) {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getUint8(offset);
        return value;
    }

    // readUInt16LE(offset);
    readUInt16BE(offset)
    {
        if (offset == undefined) {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getUint16(offset, false);
        return value;
    }

    // readUInt32LE(offset);
    readUInt32BE(offset)
    {
        if (offset == undefined) {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getUint32(offset, false);
        return value;
    }

    readInt8(offset)
    {
        if (offset == undefined) {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getInt8(offset);
        return value;
    }

    // readInt16LE(offset);
    readInt16BE(offset)
    {
        if (offset == undefined) {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getInt16(offset, false);
        return value;
    }

    // readInt32LE(offset);
    readInt32BE(offset)
    {
        if (offset == undefined)
        {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getInt32(offset, false);
        return value;
    }

    // readFloatLE(offset);
    readFloatBE(offset)
    {
        if (offset == undefined) {
            offset = 0;
        }
        const view = new DataView(this.innerbuffer);
        let value = view.getFloat32(offset, false);
        return value;
    }

    // readDoubleLE(offset);
    readDoubleBE(offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            let value = view.getFloat64(offset, false);
            return value;
        }

        // reverse(): this;
        // swap16(): Buffer;
        // swap32(): Buffer;
        // swap64(): Buffer;

        // writeBigInt64BE(value: bigint, offset);
        // writeBigInt64LE(value: bigint, offset);
        // writeBigUInt64BE(value: bigint, offset);
        // writeBigUInt64LE(value: bigint, offset);
        // writeUIntLE(value, offset, byteLength);
        // writeUIntBE(value, offset, byteLength);
        // writeIntLE(value, offset, byteLength);
        // writeIntBE(value, offset, byteLength);

        writeUInt8(value, offset)
        {
            //var val_array = new Uint8Array(this.innerbuffer, number,1);
            //val_array.set([value],0);
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setInt8(offset, value);
            return offset + 1;

        }
        // writeUInt16LE(value, offset);
        writeUInt16BE(value, offset)
        {
            // var val_array = new Uint8Array(this.innerbuffer, number,1);
            // val_array[0] = value;
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setUint16(offset, value, false);
            return offset + 2;
        }
        // writeUInt32LE(value, offset);
        writeUInt32BE(value, offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setUint32(offset, value, false);

            return offset + 4;
        }
        writeInt8(value, offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setInt8(offset, value, false);
            return offset + 1;
        }
        //  writeInt16LE(value, offset);
        writeInt16BE(value, offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setInt16(offset, value, false);
            return offset + 2;
        }
        //  writeInt32LE(value, offset);
        writeInt32BE(value, offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setInt32(offset, value, false);
            return offset + 4;
        }
        // writeFloatLE(value, offset);
        writeFloatBE(value, offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setFloat32(offset, value, false);
            return offset + 4;
        }
        // writeDoubleLE(value, offset);
        writeDoubleBE(value, offset)
        {
            if (offset == undefined) {
                offset = 0;
            }
            const view = new DataView(this.innerbuffer);
            view.setFloat64(offset, value, false);
            return offset + 8;
        }

        fill(value, offset, end, encoding)
        {
            this.innerbuffer.fill(value,offset,end);
            return this;
        }

        /**
             * @param target A `Buffer` or {@link Uint8Array} to copy into.
             * @param [targetStart=0] The offset within `target` at which to begin writing.
             * @param [sourceStart=0] The offset within `buf` from which to begin copying.
             * @param [sourceEnd=buf.length] The offset within `buf` at which to stop copying (not inclusive).
             * @return The number of bytes copied.
             */
        copy(target, targetStart, sourceStart, sourceEnd){
             return this.innerbuffer.copy(target,targetStart, sourceStart, sourceEnd)
        }
    }


    var     nodebuffer = createNodeBuffer(32);
    let    offset = 0;
    offset = nodebuffer.writeFloatBE(99.99, 0);
    offset = nodebuffer.writeDoubleBE(99.99, offset);

    offset = nodebuffer.writeUInt8(100,offset);
    offset = nodebuffer.writeUInt16BE(65534,offset);
    offset = nodebuffer.writeUInt32BE(65534,offset);
    console.log("nodebuffer is",    nodebuffer)

    let    litebuffer = new LiteBuffer(32);
    offset = 0;
    offset = litebuffer.writeFloatBE(99.99, 0);
    offset = litebuffer.writeDoubleBE(99.99, offset);
    int8offset = offset;
    offset = litebuffer.writeUInt8(100,offset);
    int16offset = offset;
    offset = litebuffer.writeUInt16BE(65534,offset);
    int32offset = offset;
    offset = litebuffer.writeUInt32BE(65533,offset);
    console.log(litebuffer.innerbuffer);
    console.log(litebuffer.readUInt8(int8offset));
    console.log(litebuffer.readUInt16BE(int16offset));
    console.log(litebuffer.readUInt32BE(int32offset));

    let a = "this is atest";
    a.copy(litebuffer.innerbuffer,0);
    console.log(litebuffer)
